<template>
    <div class="container">
        <div class="chart-content">
            <div :id="container" class="chart-views"></div>
        </div>
    </div>
</template>
<script>
import { dateFormatter, deepAssign, formatterNumber } from '@/common/js/util.js'
import Highcharts from 'highcharts';
export default {
    props: ['dataArr', 'container', '_particleSize', 'valueType'],
    data() {
        return {
            charts: null,
            particleSize: 'day', // 粒度
        }
    },
    created() {
        this.particleSize = this._particleSize || 'day';
    },
    methods: {
        formatData(data = []) {
            let particleSize = this.particleSize, keys = 0, _data = [];
            for(let [_key, value] of data.entries()) {
                let _value = this.formatStringToTime(value[0]), date_value = _value;
                if(!_data[keys]) {
                    _data[keys] = [[], 0]; // [] - 存储日期, 0 // 总值 
                }
                //_data[keys][1] = Math.ceil(value[1] + _data[keys][1]); // 计算总值

                if(particleSize == "week" && this.valueType === "1") { // c2 表示来源累计用户，累计如果粒度是周或月则取一个周期最后一天的数据即可，不需要叠加
                    /*if(new Date(_value).getDay() == 0) {
                        _data[keys][1] = Math.ceil(value[1] + _data[keys][1]); // 计算每周最后一天数据
                    }*/
                    if (value[1] > 0) {
                        _data[keys][1] = value[1]
                    }
                } else if(particleSize == "month" && this.valueType === "1") {
                    /*if(new Date(_value).getMonth() != new Date(_value + 24 * 3600 * 1000).getMonth()) {
                        _data[keys][1] = Math.ceil(value[1] + _data[keys][1]); // 计算每月最后一天数据
                    }*/
                    if (value[1] > 0) {
                        _data[keys][1] = value[1]
                    }
                } else {
                    _data[keys][1] = Math.ceil(value[1] + _data[keys][1]); // 计算总值
                }

                if(particleSize == 'week') date_value = dateFormatter('MM.DD', _value)
                if(_data[keys][0][0]) {
                    _data[keys][0][1] = date_value // 如果是周 月 不断更换直到最后一天
                } else {
                    _data[keys][0].push(date_value) // 如果是周 月 存储第第一天
                }
                if(particleSize == 'day' || 
                   particleSize == 'week' && new Date(_value).getDay() == 0 || 
                   particleSize == 'month' && new Date(_value).getMonth() != 
                   new Date(_value + 24 * 3600 * 1000).getMonth()) 
                {
                    keys++;
                }
            }
            _data = _data.map(item => {
                if(particleSize == 'day') {
                    //item[0] = this.formatStringToTime(item[0][0]) // 转时间戳
                    item[0] = item[0][0]
                } else if(particleSize == 'week') {
                    item[0] = item[0].join("-") // 转字符串
                } else if(particleSize == 'month') {
                    item[0] = dateFormatter('YYYY.MM', item[0][0]) // 转月份字符串
                }
                return item;
            })
            return _data;
        },
        formatStringToTime(str) {
            if(typeof str !== 'string') return str;
            return new Date(str.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3")).getTime()
        },
        chartInit(dataArr = null) {
            const that = this;
            dataArr = deepAssign({}, dataArr);

            if(this.particleSize != 'sort') {
                dataArr.series = dataArr.series.map(item => {
                    item.data = this.formatData(item.data);
                    return item;
                })
            }

            this.charts = Highcharts.chart(this.container, {
                chart: Object.assign({ 
                    type: 'column', 
                    backgroundColor: 'none', // 图表背景色, 设置为空，否则浮动时会遮挡 自定义的label
                    reflow: true, // 当窗口改变尺寸，重新适应
                }, dataArr.chart || {}), 
	            title: Object.assign({
                    text: null,
                    align: 'center',
                    useHTML: true,
                    margin: 12,
                    y: 5,
                    style: { 
                        "color": dataArr.series[0].linecolor, 
                        "fontSize": "12px",
                        "display": 'block',
                        "backgroundColor": Highcharts.color(dataArr.series[0].linecolor).setOpacity(0.1).get('rgba'),
                        "zIndex": 1,
                    }
                }, dataArr.title || {}),
                credits: { enabled: false },  // 去版权水印
                exporting: { enabled: false }, // 隐藏导出
                yAxis: deepAssign({
                    title: null,
                    lineWidth: 0,
                    gridLineWidth: 1,
                    gridLineColor: '#355B98',
                    maxPadding: 0.1, // 相对于轴长的最大填充，当最大值出现在接近边缘时或者超边，设置此参数可以有效调整
                    minRange: 1, // 最小范围
                    min: 0, // 最小刻度值
                    allowDecimals: false, // 禁止出现小数
                    labels: {
                        style: {
                            color: '#7BA2E1'
                        }
                    },
			        // showFirstLabel: false, // 不显示第一个坐标值 0 
                }, dataArr.yAxis || {}),
                xAxis: deepAssign([{
                    type: that.particleSize == 'day' ? 'datetime' : 'category',
                    dateTimeLabelFormats: {
                        day: '%Y%m%d' // 时间格式化
                    },
                    lineWidth: 1,
                    lineColor: '#355B98',
                    tickColor: '#355B98',
                    tickWidth: 1,
                    tickLength: 5, // 刻度线长度
                    labels: {
                        useHTML: false,
                        style: {
                            color: '#7BA2E1'
                        },
                        formatter: function(e) {
                            if(this.axis.options.type == 'datetime') {
                                return dateFormatter("MM-DD", this.value) // 标签格式化，针对缩小时日期变为英文格式
                            } else if(that.particleSize == "sort") {
                                return `<div class="labels-box"><div class="sort"><i class="i${e.pos + 1}"></i>TOP${e.pos + 1}</div><p><span>${this.value}</span></p></div>`
                            } else {
                                return this.value;
                            }
                        }
                    },
                    tickPositioner: function (min, max) {
                        if(that.particleSize == 'sort') return;
                        const interval = this.options.type == 'datetime' ? 24 * 3600 * 1000 : 1;
			        	const diff = (this.dataMax - this.dataMin) / (interval), width = this.width;
                        let n = 12;
                        if(that.particleSize == "week") {
                            n = 10;
                        }
                        let step = Math.floor(width * n / 1080); // 根据宽度自动调整 步阶(width = 1080px 可以放 10 个刻度)
                        if(step > diff) {
                            step = diff
                        }
                        var positions = [],
			        		tick = Math.floor(this.dataMin),
			        		increment = Math.ceil(diff / step) * interval; // 增量
			        	for (tick; tick - increment < this.dataMax; tick += increment) {
                            // if(tick < this.dataMax && (tick + increment) > this.dataMax) {
                            if(tick > this.dataMax) {
                                tick = this.dataMax;
                            }
			        		positions.push(tick);
			        	}
                        if(positions.length < 1) positions = [0] // 当min = max = 0的情况下，需默认给出一个初始值
			        	return positions;
			        },
                }], dataArr.xAxis || []),
                tooltip: Object.assign({
                    enabled: dataArr.series[0].data.length >= 15 ? true : false,
                    shared: true, // 数据共享
                    borderRadius: 6,  // 当前highcharts版本 提示框为 square 值时，圆角值无效 
                    borderWidth: 0,
                    backgroundColor: 'rgba(255, 255, 255, 0.9)',
                    useHTML: true,
                    formatter: function() {
                        let value = this.points[0].point.series.xAxis.options.type == 'datetime' ? dateFormatter("MM-DD", this.x) : (typeof this.points[0].key == "number" ? "" : this.points[0].key);
                        const valueSuffix = dataArr.tooltip ? dataArr.tooltip.valueSuffix : '';
                        if(that.particleSize == "sort" && parseInt(this.y) <= 0) {
                            return false
                        }
                        return `<small style="margin-bottom:5px;display:block">${value}</small><span style="color:${this.points[0].color.stops[0][1]};font-size:14px">●</span> ${this.points[0].series.name}: ${formatterNumber(this.y, 100000, 2, true)}${valueSuffix}<br/>`
                    },
                    padding: 12
                }, dataArr.tooltip || {}),
                legend: {
                    enabled: false, // 隐藏图例
                },
                plotOptions: {
                    column: {
                        borderWidth: 0,
                        maxPointWidth: 36, // 柱形最大宽度
                        cursor: 'pointer',
                        dataLabels: {
                            enabled: dataArr.dataLabels === false ? false : (dataArr.series[0].data.length < 15 ? true : false),
                            color: '#7BA2E1',
                            //format: '{y}',
                            formatter: function() {
                                if(that.particleSize == "sort") {
                                    // const valueSuffix = dataArr.tooltip ? dataArr.tooltip.valueSuffix : '';
                                    const valueSuffix = '';
                                    if(this.y > 0) return formatterNumber(this.y, 10000, 2, true) + valueSuffix
                                    else return ''
                                } else {
                                    return formatterNumber(this.y, 10000, 2, true)
                                }
                            },
                            style: {
                                'fontWeight': 'normal',
                                'textOutline' : 'none',
                            },
                            crop: false, // 防止标签和柱形重叠
                            overflow: 'none', // 防止标签和柱形重叠
                            y: 0, // 偏移，指和柱形顶部缘的距离
                        },
                        pointPadding: 0, // 设置2根柱状之间的间距，默认 0.1
                        point: Object.assign({}, dataArr.point || {})
                    },
                    bar: {
                        borderWidth: 0,
                        maxPointWidth: 8, // 柱形最大宽度
                        cursor: 'pointer',
                        dataLabels: {
                            enabled: dataArr.series[0].data.length < 15 ? true : false,
                            color: '#7BA2E1',
                            //format: '{y}次',
                            formatter: function() {
                                const valueSuffix = dataArr.tooltip ? dataArr.tooltip.valueSuffix : '';
                                if(that.particleSize == "sort") {
                                    if(this.y > 0) return formatterNumber(this.y, 10000, 2, true) + valueSuffix
                                    else return ''
                                } else {
                                    return formatterNumber(this.y, 10000, 2, true) + valueSuffix
                                }
                            },
                            style: {
                                'fontWeight': 'normal',
                                'textOutline' : 'none',
                            },
                            x: 1, // 偏移，指和柱形右侧边缘的距离
                            crop: false, // 防止标签和柱形重叠
                            overflow: 'none', // 防止标签和柱形重叠
                        },
                        pointPadding: 0, // 设置2根柱状之间的间距，默认 0.1
                    }
                },
                labels: deepAssign({}, dataArr.labels || {}),
                series: dataArr.series
            })
        }
    },
    watch: {
        'dataArr.series': function(val, oldVal) {
            if(this.dataArr.particleSize) {
                this.particleSize = this.dataArr.particleSize; // 更新粒度
            }
            Highcharts.setOptions({
                lang: { thousandsSep: ',' } 
            });
            this.chartInit(this.dataArr)
        },
        'dataArr.resize': function(val, oldVal) {
            this.dataArr.func.call(this, this.dataArr);
        }
    }
}
</script>
<style lang="scss" scoped>
    .container, .chart-views{
        width: 100%;
        height: 100%;
    }
    .chart-content {
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        padding: 0;
    }
    /deep/.highcharts-halo.highcharts-color-undefined{
        fill: transparent; // 清除标记点 阴影背景
    }
    /deep/.highcharts-container {
        .highcharts-title {
            border-radius: 4px;
            .highcharts-title-span {
                border: 1px solid #4293F4;
                padding: 3px 12px 2px;
                border-radius: 4px;
                display: block;
                // background-color: #214886;
            }
        }
        // 设置提示框图层高于图表层
        div.highcharts-tooltip{ 
            position: relative;
            z-index: 3;
        }
        // 将图表层改为浮动，层级让他高于底部自定义label的图层，并且要把chart的背景设置为空
        .highcharts-root {
            position: absolute;
            z-index: 2;
        }
        .highcharts-xaxis-labels {
            z-index: 1;
        }
    }
</style>